package com.zhixiang.core.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.Writer;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

/**
 * 文件操作
 * 
 * @author whw
 * @version 1.0
 */
public class FileUtils implements Serializable {

    /** 描述 */

    private static final long serialVersionUID = -2966425521742064947L;

    /**
     * 定义文件模板下载文件名称
     */
    public static final String TEMPLATEPAHT = "/templet/";
    /**
     * 文件字符集
     */
    private static final String CHARACTER_SET = "UTF-8";

    /**
     * 文件内容 类型
     */
    private static final Map<String, String> CONTENT_TYPE = new HashMap<String, String>();

    static {
        CONTENT_TYPE.put("xls", "application/vnd.ms-excel");
        CONTENT_TYPE
                .put("xlsx",
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.template");
        CONTENT_TYPE.put("rar", "application/octet-stream");
        CONTENT_TYPE.put("zip", "application/zip");
        CONTENT_TYPE.put("doc", "application/msword");
        CONTENT_TYPE.put("jpg", "image/jpeg");
        CONTENT_TYPE.put("jpe", "image/jpeg");
        CONTENT_TYPE.put("jpeg", "image/jpeg");
        CONTENT_TYPE.put("gif", "image/gif");
        CONTENT_TYPE.put("ai", "application/postscript");
        CONTENT_TYPE.put("txt", "text/plain");
    }

    /**
     * 图片类型
     */
    public static final List<String> IMG_TYPES = new ArrayList<String>();
    static {
        IMG_TYPES.add("jpg");
//        IMG_TYPES.add("jpeg");
//        IMG_TYPES.add("bmp");
//        IMG_TYPES.add("gif");
        IMG_TYPES.add("png");
    }
    
    /**
     * 读取的文件
     */
    private String fileIn;

    /**
     * 读取時文件用的编码
     */
    private String fileInEn;

    /**
     * 写出的文件
     */
    private String fileOut;

    /**
     * 写出時文件用的编码
     */
    private String fileOutEn;

    /**
     * 导入文件路径
     */
    public static String importFilePath = "E:\\importFile.txt";

    /**
     * 获取源文件的编码
     * 
     * @param filePath
     *            源文件所在的绝对路径
     * @return 返回文件编码
     */
    public String getFileEnCode(String filePath) {
        InputStream inputStream = null;
        String code = "";
        try {
            inputStream = new FileInputStream(filePath);
            byte[] head = new byte[3];
            inputStream.read(head);
            code = "gb2312";
            if (head[0] == -1 && head[1] == -2)
                code = "UTF-16";
            if (head[0] == -2 && head[1] == -1)
                code = "Unicode";
            if (head[0] == -17 && head[1] == -69 && head[2] == -65)
                code = "UTF-8";
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return code;
    }

    /**
     * 
     * 描述
     * 
     * @param fileInPath
     *            fileInPath
     * @param fileInEncoding
     *            fileInPath
     */
    public void setFileIn(String fileInPath, String fileInEncoding) {
        this.setFileIn(fileInPath);
        this.setFileInEn(fileInEncoding);
    }

    /**
     * 
     * 描述
     * 
     * @param fileOutPath
     *            fileOutPath
     * @param fileOutEncoding
     *            fileOutEncoding
     */
    public void setFileOut(String fileOutPath, String fileOutEncoding) {
        this.setFileOut(fileOutPath);
        this.setFileOutEn(fileOutEncoding);
    }

    /**
     * 
     * 描述
     */
    @SuppressWarnings("static-access")
    public void start() {
        String str = this.read(fileIn, fileInEn);
        this.write(fileOut, fileOutEn, str);
    }

    /**
     * 读文件
     * 
     * @param fileName
     *            fileName
     * @param encoding
     *            字符编码
     * @return ""
     */
    private static String read(String fileName, String encoding) {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    new FileInputStream(fileName), encoding));
            String string = "";
            String str = "";
            while ((str = in.readLine()) != null) {
                string += str + "\n";
            }
            in.close();
            return string;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "";
    }

    /**
     * 写文件
     * 
     * @param filePath
     *            文件路径及文件名称
     * @param encoding
     *            写出的文件的编码方式
     * @param str
     *            写入信息
     * @return 是否写成成功
     */
    public static boolean write(String filePath, String encoding, String str) {
        boolean flag = false;
        try {
            if(createFilderFile(filePath)) {
                Writer out = new BufferedWriter(new OutputStreamWriter(
                        new FileOutputStream(filePath), encoding));
                out.write(str);
                out.close();
                flag = true;
            } else {
                flag = false;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            flag = false;
        }
        return flag;
    }

    /**
     * 追加写文件
     * 
     * @param filePath
     *            文件路径及文件名称
     * @param encoding
     *            写出的文件的编码方式
     * @param str
     *            写入信息
     */
    public static void appendWrite(String filePath, String encoding, String str) {
        try {
            Writer out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(filePath, true), encoding));
            out.write(str);
            out.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 验证文件是否存在
     * 
     * @param filePath
     *            文件路径
     * @return true/
     */
    public static boolean isFileExist(String filePath) {
        boolean flag = false;
        File file = new File(filePath);
        if (file.exists() && file.isFile())
        {
            flag = true;
        }
        return flag;
    }

    /**
     * 删除已经存在的文件
     * 
     * @param filePath
     *            文件路径
     * @return true/删除成功；false删除失败
     */
    public static boolean delExistFile(String filePath) {
        boolean flag = false;
        if (isFileExist(filePath)) {
            if (new File(filePath).delete()) {
                flag = true;
            }
        } else {
            flag = true;
        }
        return flag;
    }

    /**
     * 文件下载
     * 
     * @param request
     *            request
     * @param response
     *            response
     * @param filePath
     *            文件服务器地址
     * @param storeName
     *            服务器存储文件名称
     * @param realName
     *            下载提示文件名称
     * @throws Exception
     *             Exception
     */
    public static void download(HttpServletRequest request,
            HttpServletResponse response, String filePath, String storeName,
            String realName) throws Exception {
        response.setContentType("text/html;charset=" + CHARACTER_SET);
        request.setCharacterEncoding(CHARACTER_SET);
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        String fileWebPath = request.getSession().getServletContext().getRealPath("/");
        if ("".equals(filePath) || 0 == filePath.length()) {
        	filePath= FileUtils.TEMPLATEPAHT;
        }
        String downLoadPath = fileWebPath + filePath + storeName;

        long fileLength = new File(downLoadPath).length();
        String extensionName = getExtensionName(storeName);
        String downloadName = realName + "." + extensionName;
        response.setContentType(CONTENT_TYPE.get(extensionName));
        response.setHeader("Content-disposition", "attachment; filename="
                + new String(downloadName.getBytes("GBK"), "ISO8859-1"));
        response.setHeader("Content-Length", String.valueOf(fileLength));

        bis = new BufferedInputStream(new FileInputStream(downLoadPath));
        bos = new BufferedOutputStream(response.getOutputStream());
        byte[] buff = new byte[2048];
        int bytesRead;
        while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
            bos.write(buff, 0, bytesRead);
        }
        bis.close();
        bos.close();
    }

    /**
     * 文件操作 获取文件扩展名
     * 
     * @param filename
     *            filename
     * @return String
     */
    public static String getExtensionName(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length() - 1))) {
                return filename.substring(dot + 1);
            }
        }
        return filename;
    }

    /**
     * 创建文件夹
     * 
     * @param filePath
     *            文件路径
     */
    public static void createFolder(String filePath) {
        File f = new File(filePath);
        if (!f.exists()) {
            f.mkdirs();
        }
    }

    /**
     * 
     * 描述
     * @param filePath  文件路径
     * @return          true/false
     * @throws java.io.IOException
     */
    public static boolean createFilderFile(String filePath) throws IOException {
        boolean flag = false;
        File f = new File(filePath);
        if (!f.exists()) {
            if(!f.getParentFile().exists()) {
                if (f.getParentFile().mkdirs()) {
                    flag = true;
                }
            } else {
                f.createNewFile();
                flag = true;
            }
        } else {
            flag = true;
        }
        return flag;
        
    }
    
    /**
     * 删除某个文件夹下的所有文件夹和文件
     * 
     * @param delpath
     *            String
     * @throws java.io.FileNotFoundException
     *             FileNotFoundException
     * @throws java.io.IOException
     *             IOException
     */
    public static void deletefile(String delpath) throws FileNotFoundException,
            IOException {
        try {
            File file = new File(delpath);
            if (!file.isDirectory()) {
                file.delete();
            } else if (file.isDirectory()) {
                String[] filelist = file.list();
                for (int i = 0; i < filelist.length; i++) {
                    File delfile = new File(delpath + "\\" + filelist[i]);
                    if (!delfile.isDirectory()) {
                        delfile.delete();
                    } else if (delfile.isDirectory()) {
                        deletefile(delpath + "\\" + filelist[i]);
                    }
                }
                file.delete();
            }

        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

   

   
    
    /**
     * 
     * 检测与创建一级、二级文件夹、文件名 这里我通过传入的两个字符串来做一级文件夹和二级文件夹名称
     * 通过此种办法我们可以做到根据用户的选择保存到相应的文件夹下
     * 
     * @param typeName
     *            typeName
     * @param brandName
     *            typeName
     * @param fileName
     *            fileName
     * @return 文件对象
     */
    public static File creatFolder(String typeName, String brandName, String fileName) {
        File file = null;
//        typeName = typeName.replaceAll("/", ""); // 去掉"/"
        typeName = typeName.replaceAll(" ", ""); // 替换半角空格
        typeName = typeName.replaceAll(" ", ""); // 替换全角空格

//        brandName = brandName.replaceAll("/", ""); // 去掉"/"
        brandName = brandName.replaceAll(" ", ""); // 替换半角空格
        brandName = brandName.replaceAll(" ", ""); // 替换全角空格

        File firstFolder = new File(typeName); // 一级文件夹
        if (firstFolder.exists()) { // 如果一级文件夹存在，则检测二级文件夹
            File secondFolder = new File(firstFolder, brandName);
            if (secondFolder.exists()) { // 如果二级文件夹也存在，则创建文件
                file = new File(secondFolder, fileName);
            } else { // 如果二级文件夹不存在，则创建二级文件夹
                secondFolder.mkdir();
                file = new File(secondFolder, fileName); // 创建完二级文件夹后，再合建文件
            }
        } else { // 如果一级不存在，则创建一级文件夹
            firstFolder.mkdirs();
            File secondFolder = new File(firstFolder, brandName);
            if (secondFolder.exists()) { // 如果二级文件夹也存在，则创建文件
                file = new File(secondFolder, fileName);
            } else { // 如果二级文件夹不存在，则创建二级文件夹
                secondFolder.mkdirs();
                file = new File(secondFolder, fileName);
            }
        }
        return file;
    }

    /**
     * 验证文件夹是否存在
     * @param path	文件夹路径
     * @return
     */
    public static boolean isExist(String path) {
    	boolean flag = false;
    	File file = new File(path);
    	if (file.exists()) {
    		flag = true;
    	}
    	return flag;
    }
    
    public static String findSysPath(HttpServletRequest request) {
        return request.getSession().getServletContext().getRealPath("/");
    }
    
    public static String readFileLine() {
        String str = "\r\n";
        if ("\\".equals(File.separator)) {
            str = "\r\n";
        } else if ("/".equals(File.separator)) {
            str = "\r";
        }
        return str;
    }
    
    /**
     * 时间戳 文件命名
     * 
     * @param fileName
     * @return 
     * @see
     */
    public static String timeStampFile(String fileName) {
        return System.currentTimeMillis() + "." + getExtensionName(fileName);
    }
    
   
    /**
     * 文件保存数据库路径替换
     * 
     * @param path
     * @return 
     * @see
     */
    public static String filePathReplace(String path) {
    	if(!StringUtils.isEmpty(path)) {
    		path = path.replaceAll("\\\\", "/");
    	}
    	return path;
    }
    
    /**
     * 返回 fileIn 的值
     * 
     * @return fileIn
     */

    public String getFileIn() {
        return fileIn;
    }

    /**
     * 设置 fileIn 的值
     * 
     * @param fileIn
     *            fileIn
     */
    public void setFileIn(String fileIn) {
        this.fileIn = fileIn;
    }

    /**
     * 返回 fileInEn 的值
     * 
     * @return fileInEn
     */

    public String getFileInEn() {
        return fileInEn;
    }

    /**
     * 设置 fileInEn 的值
     * 
     * @param fileInEn
     *            fileInEn
     */
    public void setFileInEn(String fileInEn) {
        this.fileInEn = fileInEn;
    }

    /**
     * 返回 fileOut 的值
     * 
     * @return fileOut
     */

    public String getFileOut() {
        return fileOut;
    }

    /**
     * 设置 fileOut 的值
     * 
     * @param fileOut
     *            fileOut
     */
    public void setFileOut(String fileOut) {
        this.fileOut = fileOut;
    }

    /**
     * 返回 fileOutEn 的值
     * 
     * @return fileOutEn
     */

    public String getFileOutEn() {
        return fileOutEn;
    }

    /**
     * 设置 fileOutEn 的值
     * 
     * @param fileOutEn
     *            fileOutEn
     */
    public void setFileOutEn(String fileOutEn) {
        this.fileOutEn = fileOutEn;
    }
    
    //得到上传文件的大小
    public static String getFileSize(double paramDouble) {
        DecimalFormat localDecimalFormat = new DecimalFormat("0.00");
     
        if (paramDouble > 1073741824.0D) {
              double d = paramDouble / 1073741824.0D;
              return localDecimalFormat.format(d) + " GB";
           }
        
        if (paramDouble > 1048576.0D) {
          double d = paramDouble / 1048576.0D;
          return localDecimalFormat.format(d) + " MB";
        }
        if (paramDouble > 1024.0D) {
          double d = paramDouble / 1024.0D;
          return localDecimalFormat.format(d) + " KB";
        }
        return paramDouble + " B";
      }
}
